#include "basegaussseidelsolver.h"
#include <iostream>
using namespace std;

BaseGaussSeidelSolver::BaseGaussSeidelSolver(int _n,double mu1, double e1, QObject * parent):
        QObject(parent), n(_n), m(_n+2),k(0), f1(0), eps(1.0e-7), f2(0), h(1.0 / (_n-1)),
        x(0), coeffs_map(0), coeffs_list(0), g_tr(0), unpenetration(false), friction(false), l(_n+2, 0.0), lOld(_n+2, 0.0), lagrange(false), isStopped(false)
{

}

BaseGaussSeidelSolver::~BaseGaussSeidelSolver()
{
    cout << "Inner solver destructor worked" << endl;
}

void BaseGaussSeidelSolver::setF1(double f)
{
    f1 = f;
}

void BaseGaussSeidelSolver::setF2(double f)
{
    f2 = f;
}

void BaseGaussSeidelSolver::setEps(double e)
{
    eps = e;
}

void BaseGaussSeidelSolver::setG_tr(double gtr)
{
    g_tr = gtr;
}

void BaseGaussSeidelSolver::setUnpenetrationCondition(bool cond)
{
    unpenetration = cond;
}

void BaseGaussSeidelSolver::setFrictionCondition(bool cond)
{
    friction = cond;
}

void BaseGaussSeidelSolver::setLagrangeFunctionCondition(bool cond)
{
    lagrange = cond;
}

void BaseGaussSeidelSolver::randomlyInitialize()
{
    if  (coeffs_map.count() == 0)
        return ;
    srand(time(NULL));
    for  (int i = 0; i < k; i++)
    {
        if (coeffs_map[i] != -1)
        {
            x[i] = ((double)random() / RAND_MAX - 0.5);
            x[i+k] = ((double)random() / RAND_MAX - 0.5);
            //x[i] = x[i+k] = 0.0;
        }
        else
        {
            x[i] = x[i+k] = 0.0;
        }
    }
}

int BaseGaussSeidelSolver::solve()
{
    double dx = 1000000;
    int i = 0;
    bool ok = true;
    while (dx > eps)
    {
        if (isStopped)
            return  i;
        dx = iteration();
        cout << dx << endl;
        i++;
        if (i > 1000000)
        {
            ok  = false;
            //out << "Process stopped because too many iterations" << endl;
            break;
        }
        if (dx > 10)
        {
            ok = false;
            //out << "Process stopped because too big divergention" << endl;
            break;
        }
    }
    if (ok)
    {
        //out << "I'm done" << endl;
    }
    //for (int i = 0; i < 2* k; i++)
        //out << x[i] << endl;
    cout << "Total iterations done - " << i << endl;
    return i;
}

void BaseGaussSeidelSolver::stop()
{
    isStopped = true;
}


//double BaseGaussSeidelSolver::iteration()
//{
//    return 0;
//}

//void BaseGaussSeidelSolver::showGraph()
//{
//    return ;
//}
